import * as vscode from "vscode";
import { NotificationType, RequestType } from "vscode-languageclient/node";
import {
    DsProperties,
    DsWindowProperties,
    DsWindowPropertiesUpdateParams,
    DsWorkspacePropertiesUpdateParams,
    LanguageNotifications,
    LanguageRequests,
    OpenDialogOptions,
    QuickPickOptions,
    SelectFileBranchParams,
    SetProgramMetadataParams,
    TextPosition,
    TextRange
} from "./common/types";

export namespace TypeConverter {

    export function textPositionToPosition(textPsoition: TextPosition): vscode.Position {
        return new vscode.Position(
            Math.max(0, textPsoition.line),
            Math.max(0, textPsoition.character)
        );
    }

    export function textRangeToRange(textRange: TextRange): vscode.Range {
        return new vscode.Range(
            Math.max(0, textRange.start.line),
            Math.max(0, textRange.start.character),
            Math.max(0, textRange.end.line),
            Math.max(0, textRange.end.character)
        );
    }

}

interface LanguageClientRequestTypes {
    [LanguageRequests.getWindowConfiguration]: RequestType<void, DsProperties, void>;
    [LanguageRequests.getConfiguration]: RequestType<string, DsProperties, void>;
    [LanguageRequests.showOpenFileDialog]: RequestType<OpenDialogOptions, string[] | undefined, void>;
    [LanguageRequests.showQuickPickFile]: RequestType<QuickPickOptions, string, void>;
    [LanguageRequests.getFileCurrentBranch]: RequestType<string, string, void>;
    [LanguageRequests.getFileBranches]: RequestType<string, string[], void>;
    [LanguageRequests.selectFileBranch]: RequestType<SelectFileBranchParams, void, void>;
    [LanguageRequests.getProgramMetadata]: RequestType<string, string | undefined, void>;
    [LanguageRequests.setProgramMetadata]: RequestType<SetProgramMetadataParams, void, void>;
}

export const languageClientRequests: LanguageClientRequestTypes = {
    // on request
    [LanguageRequests.getWindowConfiguration]: new RequestType<void, DsProperties, void>(LanguageRequests.getWindowConfiguration),
    [LanguageRequests.getConfiguration]: new RequestType<string, DsProperties, void>(LanguageRequests.getConfiguration),
    [LanguageRequests.showOpenFileDialog]: new RequestType<OpenDialogOptions, string[] | undefined, void>(LanguageRequests.showOpenFileDialog),
    [LanguageRequests.showQuickPickFile]: new RequestType<QuickPickOptions, string, void>(LanguageRequests.showQuickPickFile),
    // send request
    [LanguageRequests.getFileCurrentBranch]: new RequestType<string, string, void>(LanguageRequests.getFileCurrentBranch),
    [LanguageRequests.getFileBranches]: new RequestType<string, string[], void>(LanguageRequests.getFileBranches),
    [LanguageRequests.selectFileBranch]: new RequestType<SelectFileBranchParams, void, void>(LanguageRequests.selectFileBranch),
    [LanguageRequests.getProgramMetadata]: new RequestType<string, string | undefined, void>(LanguageRequests.getProgramMetadata),
    [LanguageRequests.setProgramMetadata]: new RequestType<SetProgramMetadataParams, void, void>(LanguageRequests.setProgramMetadata),
};

interface LanguageClientNotifications {
    [LanguageNotifications.showEditor]: NotificationType<string>;
    [LanguageNotifications.closeActivateEditor]: NotificationType<string>;
    [LanguageNotifications.initializeServerWindowConfigurations]: NotificationType<DsWindowProperties>;
    [LanguageNotifications.workspaceConfigurationChanged]: NotificationType<DsWorkspacePropertiesUpdateParams>;
    [LanguageNotifications.configurationChanged]: NotificationType<DsWindowPropertiesUpdateParams>;
}

export const languageClientNotifications: LanguageClientNotifications = {
    [LanguageNotifications.showEditor]: new NotificationType(LanguageNotifications.showEditor),
    [LanguageNotifications.closeActivateEditor]: new NotificationType(LanguageNotifications.closeActivateEditor),
    [LanguageNotifications.initializeServerWindowConfigurations]: new NotificationType(LanguageNotifications.initializeServerWindowConfigurations),
    [LanguageNotifications.workspaceConfigurationChanged]: new NotificationType(LanguageNotifications.workspaceConfigurationChanged),
    [LanguageNotifications.configurationChanged]: new NotificationType(LanguageNotifications.configurationChanged),
};

export async function reloadWindow(message: string): Promise<void> {
    const reloadMessage = "重新载入";
    const value = await vscode.window.showInformationMessage(message, reloadMessage);
    if (value === reloadMessage) {
        vscode.commands.executeCommand("workbench.action.reloadWindow");
    }
}

export async function reloadWindowDueToConfigurationChanged(): Promise<void> {
    await reloadWindow("要使配置改动生效需要重新载入窗口。");
}
